<?php

namespace App\Services;

use App\Exceptions\ConditionException;
use Illuminate\Container\Container as Application;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

class BaseService
{

    /**
     * @var Application
     */
    protected $app;

    /**
     * @var Model
     */
    protected $model;


    /**
     * @param Application $app
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function __construct(Application $app)
    {
        $this->app = $app;
        $this->makeModel();
    }

    /**
     * Specify Model class name
     *
     * @return string
     */

    public function model() {}

    /**
     * 重置
     */
    public function resetModel()
    {
        $this->makeModel();
    }


    /**
     * 处理
     * @return Model
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function makeModel()
    {
        $model = $this->app->make($this->model());

        if (!$model instanceof Model) {
            throw new ConditionException("Class {$this->model()} must be an instance of Illuminate\\Database\\Eloquent\\Model");
        }

        return $this->model = $model;
    }


    /**
     * 自动设置过滤
     * @param array $map
     * @return mixed
     */
    public function seek(array $map)
    {
        $len = isset($map['len']) ? $map['len'] : 15;
        if ($len == 0) {
            return $this->filter($map)->get();
        }
        return $this->filter($map)->paginate($len);
    }


    /**
     * 更新数据
     * @param array $map
     * @param $id
     * @return Model|null
     */
    public function saveData(array $map, $id)
    {
        $info = $this->find($id);
        $info->fill($map)->save();
        return $info;
    }

    /**
     * 过滤
     * @param array $params
     * @return Model|null
     */
    public function where(array $params = [])
    {
        return $this->model->where($params);
    }

    /**
     * 键值
     * @param $name
     * @param $key
     * @return mixed
     */
    public function pluck($name, $key = null)
    {
        return $this->model->pluck($name, $key);
    }

    /**
     * @param number|int $len
     * @return mixed
     */
    public function paginate($len = 15)
    {
        return $this->model->paginate($len);
    }

    /**
     * @return mixed
     */
    public function withTrashed()
    {
        return $this->model->withTrashed();
    }


    /**
     * @return mixed
     */
    public function restore(array $params = [])
    {
        return $this->model->withTrashed()->where($params)->restore();
    }

    /**
     * 过滤
     * @param array $params
     * @return Model|null
     */
    public function filter(array $params = [])
    {
        return $this->model->filter($params);
    }

    /**
     * 查询列表
     * @param array $params
     * @return Model|null
     */
    public function list(array $params = [])
    {
        return $this->filter($params)->get();
    }

    /**
     * 数据源
     * @param array $params
     * @return Model|null
     */
    public function count(array $params = [])
    {
        return $this->model->filter($params)->count();
    }


    /**
     * 查询详情;
     * @param string $uuid
     * @return Model|null
     */
    public function find(string $uuid)
    {
        return $this->model->find($uuid);
    }

    /**
     * 更新信息;
     * @param array $data
     * @return Model|null
     */
    public function save(array $data)
    {
        $model = $this->find($data['uuid']);
        if ($model) $model->fill($data)->save();
        return $model;
    }

    /**
     * 创建信息;
     * @param array $data
     * @return Model|null
     */
    public function create(array $data)
    {
        return $this->model->create($data);
    }

    /**
     * 修改信息
     * @param array $data
     * @param $id
     * @return mixed
     */
    public function update(array $data, $id)
    {
        return $this->model->update(['id' => $id], $data);
    }

    /**
     * 删除
     * @param $id
     * @return mixed
     */
    public function delete($id)
    {
        return $this->model->where('id', $id)->delete();
    }

    /**
     * 查询为空时创建信息
     * @param array $params
     * @param array $data
     * @return Model|null
     */
    public function firstOrCreate(array $params, array $data)
    {
        return $this->model->firstOrCreate($params, $data);
    }

    /**
     * 校验手机号;
     * @param string $mobile
     * @return bool
     */
    protected function checkMobile(string $mobile): bool
    {
        return preg_match("/^1[3456789]\d{9}$/", $mobile);
    }

    /**
     * 校验邮箱;
     * @param string $account
     * @return bool
     */
    protected function checkEmail(string $account): bool
    {
        return in_array(substr($account, strripos($account, "@")), $this->getEmailMain());
    }

    /**
     * 获取邮箱类型;
     * @return array
     */
    protected function getEmailMain(): array
    {
        return ['@163.com', '@qq.com', '@gmail.com'];
    }

    /**
     * @return bool
     */
    public function beginTransaction()
    {
        DB::beginTransaction();
        return true;
    }

    /**
     * @return bool
     */
    public function rollBack()
    {
        DB::rollBack();
        return false;
    }

    /**
     * @return bool
     */
    public function commit()
    {
        DB::commit();
        return true;
    }
}
